package com.heima.search.service.iml;

import com.alibaba.fastjson.JSON;
import com.heima.common.dto.PageResponseResult;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.util.UserThreadLocalUtil;
import com.heima.search.dto.ApArticleSearchDto;
import com.heima.search.entity.ApArticleSearch;
import com.heima.search.service.IApUserSearchService;
import com.heima.search.service.IArticleSearchService;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: itheima
 * @create: 2022-05-27 10:21
 */
@Service
public class ArticleSearchServiceImpl implements IArticleSearchService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private IApUserSearchService userSearchService;

    /**
     * 根据关键字实现检索文章数据
     *
     * @param dto 检索条件
     * @return
     */
    @Override
    public ResponseResult search(ApArticleSearchDto dto) {
        try {
            //1.构建SearchRequest对象 生成请求路径 请求路径参数（指定查询索引库）
            SearchRequest searchRequest = new SearchRequest("app_info_article");

            //2.构建SearchSourceBuilder对象  封装请求体参数 包括：分页；查询方式；高亮；排序；聚合；算分函数；
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //2.1 设置查询方式 请求体参数中 query 部分 选择全文检索查询 match
            if (StringUtils.isNotBlank(dto.getSearchWords())) {
                sourceBuilder.query(QueryBuilders.matchQuery("all", dto.getSearchWords()));
            } else {
                sourceBuilder.query(QueryBuilders.matchAllQuery());
            }
            //2.2 设置分页
            Long from = (dto.getPage() - 1) * dto.getSize();
            sourceBuilder.from(from.intValue()).size(dto.getSize());

            //2.3 设置过滤字段（减少网络带宽）
            sourceBuilder.fetchSource(new String[]{"id", "authorName", "images", "layout", "title", "staticUrl"}, null);

            //3.将SearchSourceBuilder添加到SearchRequest对象
            searchRequest.source(sourceBuilder);

            //4.执行检索
            SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

            //5.处理响应业务数据
            //5.1 得到命中记录数
            long total = response.getHits().getTotalHits().value;

            //5.2 获取业务数据
            List<ApArticleSearch> list = new ArrayList<>();
            SearchHit[] hits = response.getHits().getHits();
            if (hits != null && hits.length > 0) {
                for (SearchHit hit : hits) {
                    String sourceAsString = hit.getSourceAsString();
                    ApArticleSearch apArticleSearch = JSON.parseObject(sourceAsString, ApArticleSearch.class);
                    list.add(apArticleSearch);
                }
            }

            //6.异步记录用户搜索历史
            User user = UserThreadLocalUtil.get();
            userSearchService.saveSearchRecord(dto.getSearchWords(), user.getUserId(), dto.getEquipmentId());
            return new PageResponseResult(dto.getPage(), dto.getSize(), total, list);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("关键字检索失败");
        }
    }
}
